import 'package:edu/constants/app_strings.dart';
import 'package:edu/pages/common/empty_content_widget.dart';
import 'package:edu/pages/common/shopping_cart_button.dart';
import 'package:edu/pages/main_tab/category/category_page_logic.dart';
import 'package:edu/utils/app_router.dart';
import 'package:edu/utils/app_theme.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';

class CategoryPage extends StatefulWidget {
  const CategoryPage({super.key});

  @override
  State<CategoryPage> createState() => _CategoryPageState();
}

class _CategoryPageState extends State<CategoryPage> {
  @override
  void initState() {
    super.initState();
    context.read<CategoryPageLogic>().init();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _buildAppBar(context),
      body: _buildMainBody(context),
    );
  }

  AppBar _buildAppBar(BuildContext context) {
    final tipColor = AppTheme.shared.appBarSearchTextTipColor;
    final titleStyle = Theme.of(
      context,
    ).textTheme.titleMedium?.copyWith(color: tipColor);

    return AppBar(
      title: GestureDetector(
        onTap: () {
          context.pushNamed(AppRouter.kCourseSearch);
        },
        child: Container(
          height: 36,
          padding: const EdgeInsets.symmetric(horizontal: 15),
          decoration: BoxDecoration(
            color: Theme.of(context).colorScheme.surface,
            borderRadius: BorderRadius.circular(18),
          ),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              SizedBox(
                width: 22,
                height: 22,
                child: Icon(Icons.search, color: tipColor),
              ),
              const SizedBox(width: 6),
              _RollingText(titleStyle),
            ],
          ),
        ),
      ),
      actions: const [ShoppingCartButton(), SizedBox(width: 10)],
    );
  }

  // 主体
  Widget _buildMainBody(BuildContext context) {
    return Selector<CategoryPageLogic, bool>(
      selector: (context, logic) => logic.isCategoryEmpty,
      builder: (context, isEmpty, child) {
        if (isEmpty) {
          return Selector<CategoryPageLogic, Tuple2<bool, bool>>(
            selector: (context, logic) =>
                Tuple2(logic.isLoading, logic.isError),
            builder: (context, value, child) {
              return EmptyContentWidget(
                isLoading: value.item1,
                isError: value.item2,
                reloadAction: () {
                  context.read<CategoryPageLogic>().loadCourseCategories();
                },
              );
            },
          );
        } else {
          return _buildContentWidget(context);
        }
      },
    );
  }

  // 课程主页
  Widget _buildContentWidget(BuildContext context) {
    return Consumer<CategoryPageLogic>(
      builder: (context, logic, child) {
        final categories = logic.categories ?? [];
        final majorTitles = categories.map((e) => e.title).toList();
        majorTitles.add(AppStrings.allCourses);
        return Row(
          children: [
            Container(
              width: 120,
              color: Theme.of(context).colorScheme.surface,
              child: _buildMajorCategoryWidget(context, majorTitles),
            ),
            Expanded(child: _buildMinorCategoryWidget(context)),
          ],
        );
      },
    );
  }

  // 课程二级分类
  Widget _buildMinorCategoryWidget(BuildContext context) {
    final color1 = Theme.of(context).appBarTheme.backgroundColor;
    final logic = context.read<CategoryPageLogic>();
    final minorCategories = logic.minorCategories ?? [];

    return Ink(
      color: color1,
      padding: const EdgeInsets.only(top: 20, bottom: 20),
      child: GridView.builder(
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3,
          mainAxisExtent: 100,
        ),
        itemCount: minorCategories.length + 1,
        itemBuilder: (context, index) {
          String title;
          Widget image;
          final color = Theme.of(context).textTheme.labelLarge!.color;
          if (index == 0) {
            title = AppStrings.all;
            image = Icon(Icons.apps, size: 40, color: color);
          } else {
            title = minorCategories[index - 1].title;
            final icon = minorCategories[index - 1].icon;
            image = Image.asset(
              'assets/icons/categories/$icon',
              width: 40,
              height: 40,
            );
          }
          return InkWell(
            onTap: () {
              int id;
              String nextTitle;
              if (index == 0) {
                id = logic.majorCategoryId;
                nextTitle = logic.categories![logic.majorCategoryIndex].title;
              } else {
                id = minorCategories[index - 1].id;
                nextTitle = title;
              }
              context.pushNamed(
                AppRouter.kCourseList,
                queryParameters: {'categoryId': '$id', 'title': nextTitle},
              );
            },
            child: Center(
              child: Column(
                children: [
                  const Spacer(),
                  image,
                  const SizedBox(height: 10),
                  Flexible(
                    child: Text(
                      title,
                      style: Theme.of(context).textTheme.labelLarge,
                      textAlign: TextAlign.center,
                      overflow: TextOverflow.ellipsis,
                    ),
                  ),
                  const Spacer(),
                ],
              ),
            ),
          );
        },
      ),
    );
  }

  // 课程一级分类
  Widget _buildMajorCategoryWidget(
    BuildContext context,
    List<String> majorTitles,
  ) {
    final logic = context.read<CategoryPageLogic>();
    final majorIndex = logic.majorCategoryIndex;
    final color1 = Theme.of(context).scaffoldBackgroundColor;
    final color2 = Theme.of(context).colorScheme.surface;
    final titleColor1 = Theme.of(context).colorScheme.primary;
    final titleColor2 = Theme.of(context).colorScheme.secondary;
    final normalStyle = Theme.of(
      context,
    ).textTheme.titleMedium?.copyWith(color: titleColor2);
    final selectedStyle = Theme.of(context).textTheme.titleMedium?.copyWith(
      color: titleColor1,
      fontWeight: FontWeight.bold,
    );

    return ScrollConfiguration(
      behavior: const ScrollBehavior().copyWith(scrollbars: false),
      child: ListView.builder(
        itemCount: majorTitles.length,
        itemBuilder: (context, index) {
          final title = majorTitles[index];
          final bkColor = majorIndex == index ? color1 : color2;
          final titleStyle = majorIndex == index ? selectedStyle : normalStyle;
          return Material(
            color: bkColor,
            child: InkWell(
              onTap: () {
                if (index < majorTitles.length - 1) {
                  logic.majorCategoryIndex = index;
                } else {
                  context.pushNamed(
                    AppRouter.kCourseList,
                    queryParameters: {'categoryId': '0', 'title': title},
                  );
                }
              },
              child: SizedBox(
                height: 60,
                child: ListTile(titleTextStyle: titleStyle, title: Text(title)),
              ),
            ),
          );
        },
      ),
    );
  }
}

class _RollingText extends StatefulWidget {
  final TextStyle? textStyle;

  const _RollingText(this.textStyle);

  @override
  State<_RollingText> createState() => __RollingTextState();
}

class __RollingTextState extends State<_RollingText> {
  // 每隔3秒播放
  late final Stream<int> _stream = Stream.periodic(
    const Duration(seconds: 3),
    (i) => i,
  );

  @override
  Widget build(BuildContext context) {
    return Selector<CategoryPageLogic, List<String>?>(
      selector: (context, logic) => logic.topCourseKeys,
      builder: (context, v, child) {
        return _buildMainBody(context, v);
      },
    );
  }

  Widget _buildMainBody(BuildContext context, List<String>? keys) {
    if (keys == null) {
      return Text(AppStrings.searchCourse, style: widget.textStyle);
    }

    final groupedKeys = keys;
    return StreamBuilder<int>(
      stream: _stream,
      builder: (context, snapshot) {
        final index = snapshot.data ?? 0;
        final String prevKey;
        if (index == 0) {
          prevKey = AppStrings.searchCourse;
        } else {
          prevKey = groupedKeys[(index - 1) % groupedKeys.length];
        }
        final key = groupedKeys[index % groupedKeys.length];
        final toggle = index % 2 == 1;
        return ClipRect(
          child: Stack(
            alignment: Alignment.centerLeft,
            children: [
              AnimatedSwitcher(
                duration: const Duration(milliseconds: 300),
                transitionBuilder: (child, animation) {
                  final Tween<Offset> tween;
                  if (toggle) {
                    tween = Tween<Offset>(
                      begin: const Offset(0, -1),
                      end: const Offset(0, 0),
                    );
                  } else {
                    tween = Tween<Offset>(
                      begin: const Offset(0, 1),
                      end: const Offset(0, 0),
                    );
                  }
                  return SlideTransition(
                    position: tween.animate(animation),
                    child: child,
                  );
                },
                child: toggle
                    ? const SizedBox.shrink()
                    : Text(
                        toggle ? prevKey : key,
                        key: const ValueKey<String>('key1'),
                        style: widget.textStyle,
                      ),
              ),
              AnimatedSwitcher(
                duration: const Duration(milliseconds: 300),
                transitionBuilder: (Widget child, Animation<double> animation) {
                  final Tween<Offset> tween;
                  if (toggle) {
                    tween = Tween<Offset>(
                      begin: const Offset(0, 1),
                      end: const Offset(0, 0),
                    );
                  } else {
                    tween = Tween<Offset>(
                      begin: const Offset(0, -1),
                      end: const Offset(0, 0),
                    );
                  }

                  return SlideTransition(
                    position: tween.animate(animation),
                    child: child,
                  );
                },
                child: toggle
                    ? Text(
                        toggle ? key : prevKey,
                        key: const ValueKey<String>('key2'),
                        style: widget.textStyle,
                      )
                    : const SizedBox.shrink(),
              ),
            ],
          ),
        );
      },
    );
  }
}
